fix(agentic-ci): improve dependency PR quality#787
Conversation
Greptile SummaryThis PR replaces ad-hoc grep-based transitive dependency checking with a deterministic AST-driven inventory script (
|
| Filename | Overview |
|---|---|
| scripts/audit_package_dependencies.py | New script: AST-based import/dependency inventory with transitive closure and severity classification; logic is correct and well-tested. |
| scripts/manage_agentic_ci_attempts.py | New script: extracts group-query and batch-abandon logic from inline shell Python; atomic state file updates, correct marker allowlist, proper JSON CLI interface. |
| .github/workflows/agentic-ci-daily.yml | Adds dependency inventory step, group-based PR validation loop, uv.lock presence and cleanliness checks, and LOC-delta exclusion for uv.lock; also fixes a pre-existing gap where the checkout-failure path fell through to make install-dev without continuing. |
| packages/data-designer/tests/test_dependency_audit.py | New test file: covers workspace-transitive-guaranteed (low), uncovered (high), external-transitive (low), extras-activated-transitive (low), inactive-marker-not-counted, ambiguous-module-unresolved, and override cases; all test scenarios are correct. |
| packages/data-designer/tests/test_agentic_ci_attempts.py | New test file: verifies that same-(pr_number, branch) findings are grouped together and that abandon_open_attempts marks every finding in the batch. |
| .agents/recipes/dependencies/recipe.md | Updated to reference the inventory JSON instead of ad-hoc grep, adds Severity column to report table, requires uv.lock in dependency PRs, and marks transitive-gap as batchable by target package (max 3). |
| .agents/recipes/_fix-policy.md | Consistently updated: uv.lock added to dependencies path allowlist, excluded from LOC total, post-fix gates now described as grouping by (pr_number, branch), and severity table updated to match new low/high classifications. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant W as Workflow (agentic-ci-daily)
participant AP as audit_package_dependencies.py
participant MA as manage_agentic_ci_attempts.py
participant S as runner-state.json
participant G as git / gh
Note over W,AP: Build dependency inventory (dependencies suite only)
W->>AP: --output /tmp/dependency-inventory.json
AP-->>W: "JSON {packages[].missing, unresolved_modules}"
Note over W,MA: Scope gate
W->>MA: groups --state ... --prior ...
MA->>S: read state + prior counts
MA-->>W: "OPEN_GROUPS [{pr_number, branch, finding_ids}]"
loop For each GROUP
W->>G: validate files (allowlist + LOC excl. uv.lock)
alt Scope gate fails
W->>G: gh pr close + delete branch
W->>MA: abandon --finding-ids ... --marker gate_violation
MA->>S: mark all finding IDs abandoned
end
end
Note over W,MA: Lockfile gate (dependencies only, if scope gate passed)
W->>MA: groups --state ... --prior ...
MA-->>W: OPEN_GROUPS (only still-open entries)
loop For each GROUP
W->>G: git checkout $BRANCH
alt Checkout failed
W->>MA: abandon --marker lockfile_checkout_failed
else uv.lock missing from diff
W->>MA: abandon --marker lockfile_missing
else make install-dev OK
W->>G: git diff --quiet -- uv.lock
alt uv.lock changed after install
W->>MA: abandon --marker lockfile_not_committed
end
else make install-dev failed
W->>MA: abandon --marker lockfile_verification_failed
end
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant W as Workflow (agentic-ci-daily)
participant AP as audit_package_dependencies.py
participant MA as manage_agentic_ci_attempts.py
participant S as runner-state.json
participant G as git / gh
Note over W,AP: Build dependency inventory (dependencies suite only)
W->>AP: --output /tmp/dependency-inventory.json
AP-->>W: "JSON {packages[].missing, unresolved_modules}"
Note over W,MA: Scope gate
W->>MA: groups --state ... --prior ...
MA->>S: read state + prior counts
MA-->>W: "OPEN_GROUPS [{pr_number, branch, finding_ids}]"
loop For each GROUP
W->>G: validate files (allowlist + LOC excl. uv.lock)
alt Scope gate fails
W->>G: gh pr close + delete branch
W->>MA: abandon --finding-ids ... --marker gate_violation
MA->>S: mark all finding IDs abandoned
end
end
Note over W,MA: Lockfile gate (dependencies only, if scope gate passed)
W->>MA: groups --state ... --prior ...
MA-->>W: OPEN_GROUPS (only still-open entries)
loop For each GROUP
W->>G: git checkout $BRANCH
alt Checkout failed
W->>MA: abandon --marker lockfile_checkout_failed
else uv.lock missing from diff
W->>MA: abandon --marker lockfile_missing
else make install-dev OK
W->>G: git diff --quiet -- uv.lock
alt uv.lock changed after install
W->>MA: abandon --marker lockfile_not_committed
end
else make install-dev failed
W->>MA: abandon --marker lockfile_verification_failed
end
end
Reviews (5): Last reviewed commit: "Merge branch 'main' into andreatgretel/f..." | Re-trigger Greptile
Code Review: PR #787 — fix(agentic-ci): improve dependency PR qualitySummaryThis PR reworks the agentic-CI dependencies suite to make its dependency audit deterministic and its fix PRs safer:
Change is well-scoped and matches the stated validation (991 passed, ruff clean, FindingsCorrectness — script looks sound
Nit (low) — shadowing of the imported
Determinism caveat (informational, not a defect)
Workflow gate — logic is correct
Docs/recipe consistency
Test coverage
Structural ImpactStructural Impact (graphify, 2.3s)Risk: LOW (localized change)
VerdictApprove (non-blocking nits). The new script is correct, hermetically testable, and the severity model is a genuine improvement over the prior grep-based transitive check. The workflow lockfile gate closes a real failure mode (deps that pass the old lockfile but don't resolve standalone). None of the findings block merge:
All changes are confined to |
|
Thanks for putting this together, @andreatgretel! SummaryThis PR replaces the dependency suite's grep-based discovery with a structured AST/import-metadata inventory, distinguishes guaranteed declaration gaps from uncovered ones, batches compatible fixes, and requires dependency PRs to carry a clean regenerated lockfile. The implementation matches the stated intent, but two edge cases in the new classification and batching behavior are worth fixing before merge. FindingsWarnings — Worth addressing
What Looks Good
VerdictNeeds changes — preserve requirement markers/extras in closure classification, and make batched PR validation/state updates operate once per shared PR rather than once per finding. This review was generated by an AI assistant. |
|
Addressed the review feedback:
|
|
Circling back on this one, @andreatgretel — took another pass now that it's in shape. Overall it's holding up well: the AST inventory reads cleanly, ruff is happy, the three new tests pass, and the workflow YAML parses. A couple of things are still worth a look before merge, but nothing that changes the shape of the PR. Still worth addressing
Minor / optional
Still looking good
VerdictNeeds changes — no correctness issues, but the This review was generated by an AI assistant. |
|
Addressed the follow-up feedback:
|
nabinchha
left a comment
There was a problem hiding this comment.
Re-reviewed after c70f2006 (fix: address dependency audit review) — thanks for the thorough turnaround, @andreatgretel. Both earlier concerns are resolved and the extra refactoring is a genuine improvement.
What got addressed
uv.lockvs the 50-LOC cap — the scope gate now excludes the lockfile fromLOC_DELTAviagit diff --shortstat ... -- ':(exclude)uv.lock'(dependencies suite only), and_fix-policy.mddocuments thatuv.lockstill counts toward the 3-file cap and the allowlist but not the LOC total. That's exactly the split I was hoping for — the two gates are no longer mutually unsatisfiable.- Environment-relative marker evaluation — now called out explicitly with a comment, and marker handling was upgraded to propagate selected extras through the closure (
requirement_dependencies+ theselected_extrasthreading), sopydantic[email]correctly guaranteesemail-validator. Nice — that's better than the one-liner I suggested. distributionshadowing — renamed todistribution_namethroughoutaudit_repository.- Test coverage — the previously-untested branches now have cases: selected-extra guarantee, inactive project marker, ambiguous module →
unresolved_modules, and theMODULE_DISTRIBUTION_OVERRIDESpath. TYPE_CHECKING/guarded imports — the intentional over-report is now documented inline onimported_modules.
Bonus: extracting the inline gate Python into scripts/manage_agentic_ci_attempts.py (with groups/abandon subcommands + tests) and grouping attempts by (pr_number, branch) so a batched PR is validated once is a real readability and correctness win over the duplicated heredocs.
Verified locally: ruff check + ruff format --check clean on all four changed Python files, the workflow YAML parses, and the audit/attempts test files pass (9 passed).
Minor / optional
scripts/audit_package_dependencies.py:58—dependencies[name]as a bare statement relies on thedefaultdictside effect to seed an empty-extras entry for a{{ version }}template dep. It works, butdependencies.setdefault(name, set())would make the intent obvious to the next reader (and won't trip anyone reaching for a "useless expression" cleanup).
Verdict
Ship it (with nits) — everything from the prior review is handled, the new helper is well-tested, and only the one cosmetic setdefault nit remains, entirely take-it-or-leave-it.
This review was generated by an AI assistant.
Summary
uv.lockValidation
.venv/bin/ruff check --fix ..venv/bin/ruff format ..venv/bin/pytest packages/data-designer/tests(991 passed, 1 skipped).venv/bin/python scripts/update_license_headers.py --checkuv lock --checkgit diff --check